package com.google.gwt.gwtpages.client;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.google.gwt.user.client.Command;

public class GotoPageCommand implements Command {

	private Pages pages;
	private Map<String, Serializable> parameterMap;
	private Map<String, Object> transientParameterMap;
	private List<Serializable> parameterList;
	private boolean addHistoryToken = true;
	private String pageToken;
	private PageRequestSession session;

	GotoPageCommand(String pageToken, Pages pages) {
		this(pageToken, new PageRequestSession(), pages);
	}

	GotoPageCommand(String pageToken, PageRequestSession session, Pages pages) {
		this.pageToken = pageToken;
		this.session = session;
		this.pages = pages;
	}

	public void execute() {
		pages.gotoPage(this);
	}

	public Map<String, Object> getTransientParameterMap() {
		return getTransientParameterMap(true);
	}

	Map<String, Object> getTransientParameterMap(boolean doCreate) {
		if (doCreate && null == transientParameterMap)
			transientParameterMap = new HashMap<String, Object>();
		return transientParameterMap;
	}

	public GotoPageCommand setTransientParameterMap(
			Map<String, Object> transientParameterMap) {
		this.transientParameterMap = transientParameterMap;
		return this;
	}

	public List<Serializable> getParameterList() {
		return getParameterList(true);
	}

	List<Serializable> getParameterList(boolean doCreate) {
		if (doCreate && null == parameterList)
			parameterList = new ArrayList<Serializable>();
		return parameterList;
	}

	public GotoPageCommand addParameters(Serializable... parameters) {
		if (null != parameterMap) throw new RuntimeException("You can not add both list and serializable map parameters at the same time");
		if (null != parameters) {
			for (Serializable s : parameters)
				getParameterList().add(s);
		}
		return this;
	}

	public GotoPageCommand addParameter(Serializable parameter) {
		if (null != parameterMap) throw new RuntimeException("You can not add both list and serializable map parameters at the same time");
		getParameterList().add(parameter);
		return this;
	}

	public GotoPageCommand setParameters(List<Serializable> parameters) {
		if (null != parameterMap) throw new RuntimeException("You can not add both list and serializable map parameters at the same time");
		this.parameterList = parameters;
		return this;
	}

	public GotoPageCommand addParameter(String key, Serializable value) {
		if (null != parameterList) throw new RuntimeException("You can not add both list and serializable map parameters at the same time");
		getParameterMap().put(key, value);
		return this;
	}

	public GotoPageCommand addTransientParameter(String key, Object value) {
		getTransientParameterMap().put(key, value);
		return this;
	}

	public boolean isAddHistoryToken() {
		return addHistoryToken;
	}

	public String getPageToken() {
		return pageToken;
	}

	public Map<String, Serializable> getParameterMap() {
		return getParameterMap(true);
	}

	Map<String, Serializable> getParameterMap(boolean doCreate) {
		if (doCreate && null == parameterMap)
			parameterMap = new HashMap<String, Serializable>();
		return parameterMap;
	}

	public GotoPageCommand setParameters(
			Map<String, Serializable> parameterMap) {
		if (null != parameterList) throw new RuntimeException("You can not add both list and serializable map parameters at the same time");
		this.parameterMap = parameterMap;
		return this;
	}

	public PageRequestSession getSession() {
		return session;
	}

	public GotoPageCommand addHistoryToken(boolean addHistoryToken) {
		this.addHistoryToken = addHistoryToken;
		return this;
	}
}